package com.pic.mgt.syushin.action;

import java.io.File;
import java.util.Date;

import org.springframework.dao.DataAccessException;

import com.pic.mgt.action.ActionException;
import com.pic.mgt.action.MessageRecoverActionImpl;
import com.pic.mgt.dao.syushin.SyushinBasicBusinessTargetActionInfoBean;
import com.pic.mgt.dao.syushin.SyushinBusinessTargetActionDao;
import com.pic.mgt.log.IgxLog;
import com.pic.mgt.monitor.parser.ConfirmtaionFileForTxFileParser;
import com.pic.mgt.utils.FilePathUtils;

// (送多方修改) (多了 implement SyushinMessageRecoverAction)
public class SyushinMessageRecoverActionImpl extends MessageRecoverActionImpl implements SyushinMessageRecoverAction {
	private int syushinRealMessageFilenameLen;
	private int syushinBucketMessageFilenameLen;
	private String syushinBucketOutboxStr;
	private File syushinBucketOutbox;
	private String syushinRealOutboxStr;
	private File syushinRealOutbox;
	
	@Override
	public boolean recoverMessage(String messageFilenameWithoutSuffix, String apName) {
		if (null == messageFilenameWithoutSuffix || null == apName) {
			// ********************** Log **********************
			IgxLog.messageLog.warn(this,
							"Recovering message preprocess failed. Did not provide target filename or AP name.");
			// ********************** Log **********************
			
			return false;
		}

		// ********************** Log **********************
		IgxLog.messageLog.info(this,
				"Starting recover message '{}' preprocess.",
				messageFilenameWithoutSuffix);
		// ********************** Log **********************

		boolean isProcessRecoveryMessageSuccessful =
			processRecoveryMessage(messageFilenameWithoutSuffix, apName);
		if (!isProcessRecoveryMessageSuccessful) {
			return false;
		}

		// ********************** Log **********************
		IgxLog.messageLog.info(this,
				"Recovering message '{}' preprocess completed.",
				messageFilenameWithoutSuffix);
		// ********************** Log **********************

		return true;
	}

	public boolean processRecoveryMessage(String messageFilenameWithoutSuffix, String apName) {
		if (null == messageFilenameWithoutSuffix || messageFilenameWithoutSuffix.isEmpty()) {
			// ********************** Log **********************
			IgxLog.messageLog.warn(this,
							"Recovering message failed. Did not provide transaction file name or AP name.");
			// ********************** Log **********************
			
			return false;
		}
		
		
		// 取得位於訊息目錄下的相關檔案
		
		File[] messageRelatedFiles;
		try {
			messageRelatedFiles = getMessageRelatedFiles(messageFilenameWithoutSuffix, apName);
		} catch (ActionException e) {
			return false;
		}
		// 交易檔
		File transactionFile = messageRelatedFiles[0];
		// 交易檔的確認檔
		File confirmationFileForTxFile = messageRelatedFiles[1];
		// 訊息的確認檔
		File confirmationFileForMsgFile = messageRelatedFiles[2];
		
		
		boolean isCheckAndDoRecoverActionSuccessful =
						super.checkAndDoRecoverAction(transactionFile,
													  confirmationFileForTxFile,
													  confirmationFileForMsgFile);
		if (!isCheckAndDoRecoverActionSuccessful) {
			return false;
		}
		
		return true;
	}
	
	private File[] getMessageRelatedFiles(String messageFilenameWithoutSuffix, String apName) throws ActionException {
		File messageFolder = null;
		
		int messageFilenameWithoutSuffixLen = messageFilenameWithoutSuffix.length();
		if (messageFilenameWithoutSuffixLen == this.syushinRealMessageFilenameLen) {
			// 即時集信配信交易
			messageFolder = this.syushinRealOutbox;
		}
		else if (messageFilenameWithoutSuffixLen == this.syushinBucketMessageFilenameLen) {
			// Bucket 集信配信交易
			messageFolder = this.syushinBucketOutbox;
		}
		else {
			// 找不到符合的集信訊息類別
			
			// ********************** Log **********************
			IgxLog.messageLog.error(this,
					"SUDA-289 Recovering message '{}' preprocess can't identify the business type of the message.",
					messageFilenameWithoutSuffix);
			// ********************** Log **********************
			
			throw new ActionException("");
		}
		
		// 取得位於訊息目錄下的交易檔 
		File transactionFile = FilePathUtils.multiPathConcat(messageFolder.getAbsolutePath(),
														     apName,
														     messageFilenameWithoutSuffix);
		
		// 取得位於訊息目錄下的訊息確認檔
		File confirmationFileForMsgFile = FilePathUtils.multiPathConcat(messageFolder.getAbsolutePath(),
																	    apName,
																	    messageFilenameWithoutSuffix + super.messageConfirmationFilenameSuffix);
		
		
		// 取得位於訊息目錄下交易檔的確認檔
		File confirmationFileForTxFile = ConfirmtaionFileForTxFileParser.getConfirmationFile(transactionFile);
		
		return new File[] {transactionFile,
						   confirmationFileForTxFile,
						   confirmationFileForMsgFile};
	}
	
	@Override
	protected Date[] getTransactionFileTimeInfo(File transactionFile) throws DataAccessException {
		// 先取得 AP Name 出來
		String apName = transactionFile.getParentFile().getName();
		
		SyushinBasicBusinessTargetActionInfoBean syushinBasicBusinessTargetActionInfoBean = null;

		syushinBasicBusinessTargetActionInfoBean = 
				((SyushinBusinessTargetActionDao)this.businessTargetActionDao).
								findSyushinBusinessTargetActionInfoByFileNameAndApName(
										transactionFile.getName(),
										apName);

		if (null == syushinBasicBusinessTargetActionInfoBean) {
			return null;
		}
		else {
			return new Date[] {syushinBasicBusinessTargetActionInfoBean.getCreatingTime(),
							   syushinBasicBusinessTargetActionInfoBean.getLastTransactionTime()};
		}		
	}
	
	// --- getter and setter ---

	public void setSyushinRealMessageFilenameLen(int syushinRealMessageFilenameLen) {
		this.syushinRealMessageFilenameLen = syushinRealMessageFilenameLen;
	}

	public void setSyushinBucketMessageFilenameLen(
			int syushinBucketMessageFilenameLen) {
		this.syushinBucketMessageFilenameLen = syushinBucketMessageFilenameLen;
	}

	public void setSyushinBucketOutboxStr(String syushinBucketOutboxStr) {
		this.syushinBucketOutboxStr = syushinBucketOutboxStr;
		this.syushinBucketOutbox = new File(syushinBucketOutboxStr);
	}

	public void setSyushinRealOutboxStr(String syushinRealOutboxStr) {
		this.syushinRealOutboxStr = syushinRealOutboxStr;
		this.syushinRealOutbox = new File(syushinRealOutboxStr);
	}

}
